package com.dragon.pear.base.http;

import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.Toast;

import com.chris.dev.base.libs.v1.http.protocols.HttpResult;
import com.chris.dev.base.libs.v1.http.results.PageResult;
import com.chris.libs.devtools.x.v1.utils.JsonUtils;
import com.chris.libs.devtools.x.v1.utils.LoggerUtils;
import com.chris.libs.devtools.x.v1.utils.UtilsManager;
import com.chris.libs.http.x.v1.CompleteCallback;
import com.chris.libs.http.x.v1.NetCallback;
import com.chris.libs.http.x.v1.NetResponse;
import com.dragon.pear.base.dialog.LoadingDialog;
import com.dragon.pear.base.R;

import java.util.ArrayList;
import java.util.List;

/**
 * Create by Chris Chan
 * Create on 2023/4/12 4:48
 * Use for:
 * Explain:
 */
public class SuccessStatusNetCallback<T> extends NetCallback<HttpResult<T>> {
    private static final int ISSUE_APP_REQUEST = 0;
    private static final int ISSUE_API_ERROR = 1;
    private static final int ISSUE_API_DATA_EMPTY = 2;

    private CompleteCallback<T> completeCallback;

    //容器控件
    private View view;
    //加载动画
    private LoadingDialog loadingDialog;

    public SuccessStatusNetCallback() {
    }

    public SuccessStatusNetCallback(View view) {
        this.view = view;
    }

    public SuccessStatusNetCallback(CompleteCallback<T> completeCallback) {
        this.completeCallback = completeCallback;
    }

    public SuccessStatusNetCallback(View ownView, CompleteCallback<T> completeCallback) {
        this.view = ownView;
        this.completeCallback = completeCallback;
    }

    public SuccessStatusNetCallback<T> with(View ownView) {
        this.view = ownView;
        return this;
    }

    public SuccessStatusNetCallback(LoadingDialog loadingDialog) {
        this.loadingDialog = loadingDialog;
    }

    public SuccessStatusNetCallback(View view, LoadingDialog loadingDialog) {
        this.view = view;
        this.loadingDialog = loadingDialog;
    }

    @Override
    protected void onComplete(NetResponse<HttpResult<T>> netResponse) {
        System.out.println(netResponse.call.request().url().encodedPath() + " result: " + JsonUtils.objToJson(netResponse.data));
        if (null != this.loadingDialog) {
            this.loadingDialog.dismiss();
        }
        //请求错误
        if (!netResponse.isSuccess) {
            processIssue(netResponse, ISSUE_APP_REQUEST);
            return;
        }
        //接口返回错误 0为成功
        if (netResponse.data.getCode() != 0) {
            processIssue(netResponse, ISSUE_API_ERROR);
            return;
        }
        //数据为空 这里是NetResult内部数据为空，其实可以让后端在协议中以code取值来标明，这里就比较省事了。下同
        T data = netResponse.data.getData();
        System.out.println("netResponse.data.data: " + JsonUtils.objToJson(data));
        if (null == data) {
            processIssue(netResponse, ISSUE_API_DATA_EMPTY);
            return;
        }
        //列表数据为空
        if (data instanceof ArrayList) {
            if (((ArrayList<?>) data).size() == 0) {
                processIssue(netResponse, ISSUE_API_DATA_EMPTY);
                return;
            }
        }
        //分页数据为空
        if (data instanceof PageResult) {
            PageResult<?> pageResult = (PageResult<?>) data;
            List<?> dataList = pageResult.getDataList();
            if (null == dataList || dataList.size() == 0) {
                processIssue(netResponse, ISSUE_API_DATA_EMPTY);
                return;
            }
        }
        //最终请求成功的数据
        if (null != this.view) {
            ViewParent parent = this.view.getParent();
            if (parent instanceof ViewGroup) {
                ViewGroup viewGroup = (ViewGroup) parent;
                viewGroup.setBackground(null);
            }
            this.view.setVisibility(View.VISIBLE);
        }
        onSuccess(netResponse, data);
    }

    /**
     * 处理问题
     *
     * @param netResponse
     * @param type        错误类型 0 - app请求错误,由NetStatus类处理,1 - 接口请求失败,2 - 数据为空
     */
    private void processIssue(NetResponse<HttpResult<T>> netResponse, int type) {
        LoggerUtils.i("当前出错 Type: " + type);
        LoggerUtils.i("当前出错的请求是: " + netResponse.call.request().url().query());
        if (null == this.view) {
            switch (type) {
                case ISSUE_APP_REQUEST:
                    showMessage(netResponse.status.getMessage());
                    break;
                case ISSUE_API_ERROR:
                    showMessage(netResponse.data.getMessage());
                    break;
                case ISSUE_API_DATA_EMPTY:
                    //showMessage("数据为空");
                default:
                    break;
            }
            return;
        }
        //获取父级控件
        ViewParent parent = this.view.getParent();
        //父级控件必须是个容器
        //或者在深入一点，规定父级控件只能是帧布局或者相对布局，方便处理
        if (!(parent instanceof ViewGroup)) {
            showMessage("数据展示控件必须放置在一个布局视图内");
            return;
        }
        ViewGroup viewGroup = (ViewGroup) parent;
        //父级控件不能有多余的子控件
        if (viewGroup.getChildCount() > 1) {
            showMessage("布局视图内只能有一个展示控件");
            return;
        }
        //隐藏
        this.view.setVisibility(View.INVISIBLE);
        //显示状态
        switch (type) {
            case ISSUE_APP_REQUEST:
                //showMessage(netResponse.status.getMessage());
                viewGroup.setBackgroundResource(R.drawable.net_error);
                break;
            case ISSUE_API_ERROR:
                //showMessage(netResponse.data.msg);
                viewGroup.setBackgroundResource(R.drawable.net_data_error);
                break;
            case ISSUE_API_DATA_EMPTY:
                //showMessage("数据为空");
                viewGroup.setBackgroundResource(R.drawable.net_data_empty);
            default:
                break;
        }
    }

    /**
     * 处理最终成功的数据
     *
     * @param data
     */
    protected void onSuccess(NetResponse<HttpResult<T>> response, T data) {
        if (null != this.completeCallback) {
            this.completeCallback.complete(response, response.isSuccess, data);
        }
    }

    public void showMessage(CharSequence info) {
        Toast.makeText(UtilsManager.mContext, info, Toast.LENGTH_SHORT).show();
    }
}
